package org.zetaframework.base.excel.convert;

import cn.hutool.core.convert.Convert;
import cn.idev.excel.converters.Converter;
import cn.idev.excel.enums.CellDataTypeEnum;
import cn.idev.excel.metadata.GlobalConfiguration;
import cn.idev.excel.metadata.data.ReadCellData;
import cn.idev.excel.metadata.data.WriteCellData;
import cn.idev.excel.metadata.property.ExcelContentProperty;

import java.math.BigDecimal;

/**
 * 自定义Excel中的大数字转换器
 * <p>
 * 说明：
 * <pre>
 * 使用fastExcel的过程中发现，导出的数据中id由于雪花算法的缘故长度超过了15位
 * 因此在Excel中id会变成科学计数法展示。
 * 故自定义转换器解决该问题。
 * </pre>
 *
 * 参考：<br>
 * <a href="https://blog.csdn.net/weixin_40461281/article/details/119889437">文档</a>
 *
 * @author gcc
 */
public class BigNumberConverter implements Converter<Long> {

    /**
     * 返回 Java 中的对象类型
     *
     * @return Support for Java class
     */
    @Override
    public Class<?> supportJavaTypeKey() {
        return Long.class;
    }

    /**
     * 返回 excel 中的对象枚举
     *
     * @return Support for {@link CellDataTypeEnum}
     */
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    /**
     * 将 excel 对象转换为 Java 对象
     *
     * @param cellData            Excel 单元格数据。不为空
     * @param contentProperty     上下文属性。可空
     * @param globalConfiguration 全局配置。不为空
     * @return 要放入 Java 对象的数据
     * @throws Exception Exception.
     */
    @Override
    public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        return Convert.toLong(cellData.getData());
    }

    /**
     * 将 Java 对象转换为 excel 对象
     *
     * @param value               Java 数据。不为空
     * @param contentProperty     上下文属性。可空
     * @param globalConfiguration 全局配置。不为空
     * @return 要放入 Excel 的数据
     * @throws Exception Exception.
     */
    @Override
    public WriteCellData<?> convertToExcelData(Long value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        // 判断是否为空
        if (value == null) {
            return new WriteCellData<>();
        }

        // 转换成字符串，判断长度。 ps: Excel最大支持15位数字，超过则自动转换成科学计数法
        String str = Convert.toStr(value);
        if (str.length() > 15) {
            return new WriteCellData<>(str);
        }

        // 不超过15位，则转换成数字
        WriteCellData<Object> cellData = new WriteCellData<>(new BigDecimal(value));
        cellData.setType(CellDataTypeEnum.NUMBER);
        return cellData;
    }
}
